package config

import (
	"context"
	"fmt"

	"gorm.io/driver/mysql"
	"gorm.io/driver/postgres"
	"gorm.io/gorm"

	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"go.mongodb.org/mongo-driver/mongo/readpref"

	"time"
)

type DbCorm struct {
	Dbtype       string
	Dsn          string
	MongoDbDsn   string
	Maxidleconns int
	Maxopenconns int
}

type Mysql struct {
	Host     string `yaml:"host"`
	Port     string `yaml:"port"`
	User     string `yaml:"user"`
	Password string `yaml:"password"`
	Dbname   string `yaml:"dbname"`
	Option   string `yaml:"option"`
}

type Postgresql struct {
	Host     string `yaml:"host"`
	Port     string `yaml:"port"`
	User     string `yaml:"user"`
	Password string `yaml:"password"`
	Dbname   string `yaml:"dbname"`
}

type MongoDb struct {
	Host     string `yaml:"host"`
	Port     string `yaml:"port"`
	User     string `yaml:"user"`
	Password string `yaml:"password"`
	Dbname   string `yaml:"dbname"`
}

func (m *Mysql) Dsn() string {
	return m.User + ":" + m.Password + "@tcp(" + m.Host + ":" + m.Port + ")/" + m.Dbname + "?" + m.Option
}

func (p *Postgresql) Dsn() string {
	return fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", p.Host, p.Port, p.User, p.Password, p.Dbname)
}

func (m *MongoDb) Dsn() string {
	return "mongodb://" + m.Host + ":" + m.Port
}

func (d *DbCorm) InitDb() *gorm.DB {
	var err error
	var Db *gorm.DB
	switch d.Dbtype {
	case "mysql":
		Db, err = d.InitMysql()

	case "postgresql":
		Db, err = d.InitPostgresql()

	}
	if err != nil {
		panic(err.Error())
	}
	return Db
}

func (d *DbCorm) InitMysql() (*gorm.DB, error) {

	mysqlconfig := mysql.Config{
		DSN: d.Dsn,
	}
	db, err := gorm.Open(mysql.New(mysqlconfig), &gorm.Config{})

	fmt.Println(err.Error())
	if err != nil {

		return nil, err
	}
	return db, nil
}

func (d *DbCorm) InitPostgresql() (*gorm.DB, error) {
	postgreconfig := postgres.Config{
		DSN:                  d.Dsn,
		PreferSimpleProtocol: true,
	}
	db, err := gorm.Open(postgres.New(postgreconfig), &gorm.Config{})
	if err != nil {
		return nil, err
	}
	return db, nil
}

func (m *MongoDb) GetMongoClient() (*mongo.Database, error) {

	serverAPI := options.ServerAPI(options.ServerAPIVersion1)
	opts := options.Client().ApplyURI(m.Dsn()).SetServerAPIOptions(serverAPI)
	opts.SetTimeout(10 * time.Second)

	client, err := mongo.Connect(context.Background(), opts)
	if err != nil {
		return nil, err
	}
	if err = client.Ping(context.TODO(), readpref.Primary()); err != nil {
		panic(fmt.Sprintf("mongodb连接失败，错误 %s", err.Error()))
	}
	return client.Database(m.Dbname), nil
}
